#include "max31865.h"

spi_device_handle_t max31865_init(uint32_t cs, 
    uint32_t clock,bool vbias,bool autoConvert,bool wire3,bool filter50HZ)
{
    spi_device_handle_t spi_handle;
    // 错误类型返回值
    esp_err_t ret;
    // SPI设备配置
    spi_device_interface_config_t devcfg = {
        .mode = 1, // MAX31865使用SPI模式1 (CPOL=0, CPHA=1)
        .clock_speed_hz = clock,
        .spics_io_num = cs,
        .queue_size = 8};
    // 将MAX31865添加SPI设备
    ret = spi_bus_add_device(SPI_HOST, &devcfg, &spi_handle);
    if (ret != ESP_OK)
    {
        ESP_LOGI(TAG, "SPI设备添加失败: %s", esp_err_to_name(ret));
        return NULL;
    }
    // 配置寄存器设置:
    // - 启用偏置电压
    // - 自动转换模式
    // - 3线RTD连接
    // - 清除故障状态
    // - 60Hz滤波器

    uint8_t config = 0;
    if(vbias) config|= MAX31865_CONFIG_BIAS;
    if(autoConvert) config|= MAX31865_CONFIG_CONVERSION;
    if(wire3) config|= MAX31865_CONFIG_3WIRE;
    if(filter50HZ) config|= MAX31865_CONFIG_FILTER_50HZ;


    max31865_write_register(spi_handle,MAX31865_REG_CONFIG, config);
    ESP_LOGI(TAG, "MAX31865配置完成: 0x%02X", config);
    return spi_handle;
}

// 读取MAX31865寄存器
uint8_t max31865_read_register(spi_device_handle_t spi_handle,uint8_t reg_addr)
{
    spi_transaction_t t;
    uint8_t tx_data[2] = {reg_addr | 0x00, 0x00}; // 读命令
    uint8_t rx_data[2] = {0};

    memset(&t, 0, sizeof(t));
    t.length = 16; // 2字节 * 8位
    t.tx_buffer = tx_data;
    t.rx_buffer = rx_data;

    spi_device_transmit(spi_handle, &t);

    return rx_data[1]; // 返回读取的数据
}

// 写入MAX31865寄存器
void max31865_write_register(spi_device_handle_t spi_handle,uint8_t reg_addr, uint8_t data)
{
    spi_transaction_t t;
    uint8_t tx_data[2] = {reg_addr | 0x80, data}; // 写命令

    memset(&t, 0, sizeof(t));
    t.length = 16; // 2字节 * 8位
    t.tx_buffer = tx_data;

    spi_device_transmit(spi_handle, &t);
}

// 读取RTD电阻值
float max31865_read_rtd(spi_device_handle_t spi_handle)
{
    uint8_t msb = max31865_read_register(spi_handle,MAX31865_REG_RTD_MSB);
    uint8_t lsb = max31865_read_register(spi_handle,MAX31865_REG_RTD_LSB);

    uint16_t rtd_value = (msb << 8) | lsb;
    rtd_value >>= 1; // 移除D0位（故障检测位）

    return (rtd_value / 32768.0f) * R_REF;
}

// 转换为温度值
float max31865_read_ResistanceToC(float R)
{
    const float A = Ka;
    const float B = Kb;
    const float C = Kc;
    float a = B * R0;
    float b = A * R0;
    float c = R0 - R;
    float disc = b * b - 4 * a * c;

    // Try quadratic solution first (valid ≥ 0°C)
    if (disc >= 0.0f)
    {
        float T = (-b + sqrtf(disc)) / (2 * a);
        if (T >= -0.5f)
            return T;
    }

    // Else, Newton-Raphson for sub-zero
    float T = -20.0f;
    for (int i = 0; i < 25; ++i)
    {
        float T2 = T * T, T3 = T2 * T;
        float f = R0 * (1 + A * T + B * T2 + C * (T - 100.0f) * T3) - R;
        float df = R0 * (A + 2 * B * T + C * (4 * T3 - 300.0f * T2));
        if (fabsf(df) < 1e-12f)
            break;
        float dT = -f / df;
        T += dT;
        if (fabsf(dT) < 1e-4f)
            break;
    }
    return T;
}

// 检查故障状态
uint8_t max31865_read_fault(spi_device_handle_t spi_handle)
{
    return max31865_read_register(spi_handle,MAX31865_REG_FAULT);
}